// $codepro.audit.disable
/*
 * UserHandler.java
 * 
 * @version 1.0, March 17, 2011
 * CS 2340 Team 10: Cyberdyne Systems
 */
package edu.gatech.oad.cyberdoc.domain.action;

import java.util.Arrays;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.json.JSONException;
import org.json.JSONObject;

import edu.gatech.oad.cyberdoc.domain.Admin;
import edu.gatech.oad.cyberdoc.domain.Doctor;
import edu.gatech.oad.cyberdoc.domain.Patient;
import edu.gatech.oad.cyberdoc.domain.Staff;
import edu.gatech.oad.cyberdoc.domain.User;

/**
 * 
 * 
 * @author Jessie McGarry
 * @version 1.0, March 16, 2011
 */
public class UserHandler extends ActionHandler {

	/**
	 * The logger for this class.
	 */
	private static final Logger LOG;

	/**
	 * The action code this ActionHandler corresponds to.
	 */
	public static final String[] ACTION_CODES;

	static {
		ACTION_CODES = new String[] { "create_user", "read_user",
				"update_user", "delete_user" };
		LOG = Logger.getLogger("edu.gatech.oad.cyberdoc.action."
				+ "UserHandler");
	}

	/**
	 * Registers this ActionHandler with the Patient class to start receiving
	 * actions.
	 * 
	 * This class requires an array storing all of the possible time slots that
	 * an appointment may be registered.
	 */
	public UserHandler() {
		for (String code : ACTION_CODES) {
			Staff.addActionHandler(code, this);
			Doctor.addActionHandler(code, this);
			Admin.addActionHandler(code, this);
		}
	}

	@Override
	public void destroy() {
		Staff.removeActionHandler(this);
		Doctor.removeActionHandler(this);
		Admin.removeActionHandler(this);
	}

	/**
	 * Handles all commands related to TreatmentRecords
	 * 
	 * TODO Document this better
	 * 
	 * This method expects the following fields:
	 * 
	 * action: The specific action to be performed; one of: create_tr, read_tr,
	 * update_tr, delete_tr
	 * 
	 * user: The username of the user under modification
	 * 
	 * This method will return the following fields:
	 * 
	 * next: The next frame to show the user
	 * 
	 * @param source
	 *            The user that called this method
	 * @param command
	 *            The command encoding the action
	 * @return The result of performing this action
	 * @throws ActionHandleException
	 *             If a required field does not exist in the command, or if the
	 *             usernames given for the patient and doctor are invalid
	 */
	@Override
	public JSONObject handle(User source, JSONObject command)
			throws ActionHandleException {
		JSONObject response = new JSONObject();

		// TODO Clean up this method
		try {
			final String action = command.getString("action");

			if (action.matches("create_user")) {
				response = createHandler(source, command);
			} else if (action.matches("update_user")) {
				response = updateHandler(source, command);
			} else if (action.equals("read_user")) {
				response = readHandler(source, command);
			} else if (action.equals("delete_user")) {
				response = deleteHandler(source, command);
			}
		} catch (JSONException e) {
			LOG.log(Level.SEVERE, "Unexpected JSONException.", e);
			throw new ActionHandleException(e);
		}

		return response;
	}

	private JSONObject createHandler(User source, JSONObject command)
			throws ActionHandleException, JSONException {
		String username = command.getString("user");
		String password = command.getString("pass");
		String type = command.getString("type");

		if (type.equals("Patient")) {
			new Patient(username, password);
		} else if (type.equals("Nurse")) {
			new Staff(username, password);
		} else if (type.equals("Doctor")) {
			new Doctor(username, password);
		} else if (type.equals("Admin")) {
			new Admin(username, password);
		}

		return pass("view_users", command);
	}

	private JSONObject deleteHandler(User source, JSONObject command)
			throws ActionHandleException, JSONException {
		User.deleteUser(command.getString("user"));
		return pass("view_users", command);
	}

	private JSONObject updateHandler(User source, JSONObject command)
			throws ActionHandleException, JSONException {
		User user = User.getUser(command.getString("user"));

		if (user != null) {
			user.update(command.getJSONObject("fields"));
		}

		return readHandler(source, command);
	}

	private JSONObject readHandler(User source, JSONObject command)
			throws ActionHandleException, JSONException {
		final JSONObject response = new JSONObject();
		response.put("next", "view_user");

		String string = command.getString("user");
		User user = User.getUser(string);

		if (user != null) {
			response.put("user", user.toJSONObject());
		} else {
			LOG.log(Level.WARNING, "User \"" + string + "\" does not exist.");
			throw new ActionHandleException("User " + string
					+ " does not exist.");
		}

		return response;
	}

	/**
	 * Returns a string representation of this class.
	 * 
	 * @return A string representation of this class.
	 */
	@Override
	public String toString() {
		return "UserHandler (action=\"" + Arrays.toString(ACTION_CODES) + "\")";
	}
}
